package com.example.springboot.utils;

import org.apache.commons.lang3.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期时间工具籿
 */
public class DateUtils {

    private static String YMD2 = "yyyyMMdd";
    private static final String HMS = "HH:mm:ss";
    private static final String Y_M_D = "yyyy-MM-dd";
    private static final String YMDHMSS2 = "yyyyMMdd HHmmss";
    private static final String YMDHMS = "yyyy-MM-dd HH:mm:ss";
    private static final String YMDHMSZ = "yyyy-MM-dd'T'HH:mm:ss'Z'";
    private static final String YMDHMSS = "yyyy-MM-dd HH:mm:ss.SSS";

    private static final SimpleDateFormat datetimeFormat_ymdhmss = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
    private static final SimpleDateFormat datetimeFormat_ymdhms = new SimpleDateFormat(YMDHMS);
    private static final SimpleDateFormat dateFormat_ymd = new SimpleDateFormat(Y_M_D);
    private static final SimpleDateFormat dateFormat_yy = new SimpleDateFormat("yyyy");
    private static final String[] dayOfWeek = new String[]{"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};


    /**
     * 获得日期时间
     * 根据指定规则格式化时间
     *
     * @return
     */
    public static String getDateTimeStr(String date, String regex) {
        if (StringUtils.isEmpty(regex)) {
            regex = YMDHMS;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(regex);
        return dateFormat.format(date);
    }

    /**
     * 获得日期时间
     * 根据指定规则格式化时间
     *
     * @return
     */
    public static String getDateTimeStr(Date date, String regex) {
        if (StringUtils.isEmpty(regex)) {
            regex = YMDHMS;
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(regex);
        return dateFormat.format(date);
    }


    /**
     * 获得日期时间,根据指定规则格式化时间
     *
     * @return
     */
    public static Date getDateTime(String date, String regex) {
        try {
            if (StringUtils.isEmpty(regex)) {
                regex = YMDHMS;
            }
            SimpleDateFormat dateFormat = new SimpleDateFormat(regex);
            Date time = dateFormat.parse(date);
            return time;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获得日期时间,根据指定规则格式化时间
     *
     * @return
     */
    public static Date getDateTime(Date date, String regex) {
        try {
            if (StringUtils.isEmpty(regex)) {
                regex = YMDHMS;
            }
            SimpleDateFormat dateFormat = new SimpleDateFormat(regex);
            Date time = dateFormat.parse(dateFormat.format(date));
            return time;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 格式化年份
     *
     * @param date
     * @return
     */
    public static String getDateYear(Date date) {
        String year = dateFormat_yy.format(date);
        return year;
    }

    /**
     * 获取指定时间日期，将时间格式化为yyyy-mm-dd,然后拼接日期后缀
     *
     * @param date:       日期
     * @param dateSubfix： 日期后缀（hh:mm:ss）
     * @return
     */
    public static Date getCurrentDate(Date date, String dateSubfix) {
        Date parse = null;
        try {
            parse = datetimeFormat_ymdhms.parse(getCurrentDateStr(date, dateSubfix));
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return parse;
    }

    /**
     * 获取指定时间日期字符串，将时间格式化为yyyy-mm-dd,然后拼接日期后缀
     *
     * @param date:       日期
     * @param dateSubfix： 日期后缀（hh:mm:ss）
     * @return
     */
    public static String getCurrentDateStr(Date date, String dateSubfix) {
        String time = dateFormat_ymd.format(date) + " " + dateSubfix;
        return time;
    }


    /**
     * 获取指定日期的前、后时间
     *
     * @param date：时间
     * @param day：正负数，正数标识以后前几、负数标识以前几天
     * @return
     */
    public static Date getDateTimeBeforOrAlter(Date date, int day) {
        // 获取的系统当前时间
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        // 得到前、后几天
        calendar.add(Calendar.DATE, day);
        return calendar.getTime();
    }


    /**
     * 获取指定日期的前、后时间，并格式化为yyyy-MM-dd HH:mm:ss
     *
     * @param date：时间
     * @param day：正负数，正数标识以后前几、负数标识以前几天
     * @param dateSubfix:日期后缀（hh:mm:ss）
     * @return
     */
    public static Date getCurrentDateAlter(Date date, int day, String dateSubfix) {
        Date time = getDateTimeBeforOrAlter(date, day);
        Date parse = getCurrentDate(time, dateSubfix);
        return parse;
    }

    /**
     * 获取指定日期的前、后时间，并格式化为yyyy-MM-dd HH:mm:ss
     *
     * @param date：时间
     * @param day：正负数，正数标识以后前几、负数标识以前几天
     * @param dateSubfix:日期后缀（hh:mm:ss）
     * @return
     */
    public static String getCurrentDateAlterStr(Date date, int day, String dateSubfix) {
        Date time = getDateTimeBeforOrAlter(date, day);
        String parse = getCurrentDateStr(time, dateSubfix);
        return parse;
    }

    /**
     * 获取指定日期的前、后时间
     *
     * @param date：时间
     * @param day：正负数，正数标识以后前几、负数标识以前几天
     * @param regex:                    格式化规则
     * @return
     */
    public static String getDateTimeAlterStr(Date date, int day, String regex) {
        if (StringUtils.isEmpty(regex)) {
            regex = YMDHMS;
        }
        // 得到前一天
        Date time = getDateTimeBeforOrAlter(date, day);
        SimpleDateFormat dateFormat = new SimpleDateFormat(regex);
        String format = dateFormat.format(time);
        return format;
    }


    /**
     * 获取指定日期的前、后时间
     *
     * @param date：时间
     * @param day：正负数，正数标识以后前几、负数标识以前几天
     * @param regex:                    格式化规则
     * @return
     */
    public static Date getDateTimeAlter(Date date, int day, String regex) {
        try {
            // 得到前一天
            String dateTimeAlterStr = getDateTimeAlterStr(date, day, regex);
            SimpleDateFormat dateFormat = new SimpleDateFormat(regex);
            Date parse = dateFormat.parse(dateTimeAlterStr);
            return parse;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获得当前日期时间
     * <p>
     * 日期时间格式yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    public static String currentDatetimeStr() {
        return datetimeFormat_ymdhms.format(now());
    }

    /**
     * 获得当前日期时间
     * <p>
     * 日期时间格式yyyy-MM-dd HH:mm:ss
     *
     * @return Date
     */
    public static Date currentDatetime() {
        Date dateTime = null;
        try {
            dateTime = datetimeFormat_ymdhms.parse(currentDatetimeStr());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return dateTime;
    }

    /**
     * 格式化日期时闿
     * <p>
     * 日期时间格式yyyy-MM-ddTHH:mm:ssZ
     *
     * @param date
     * @return
     */
    public static String formatSolrDatetime(Date date) {
        return getDateTimeStr(new Date(), "yyyy-MM-dd'T'HH:mm:ss'Z'");
    }

    /**
     * 格式化日期时闿
     * <p>
     * 日期时间格式yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    public static String formatDatetime(Date date) {
        return getDateTimeStr(new Date(), YMDHMS);
    }

    /**
     * 格式化日期时闿
     *
     * @param date
     * @param regex 格式化模式
     * @return
     */
    public static String formatDatetimeStr(Date date, String regex) {
        return getDateTimeStr(new Date(), regex);
    }

    /**
     * 格式化日期时闿
     *
     * @return
     */
    public static String formatDatetimeStr(String regex) {
        return getDateTimeStr(new Date(), regex);
    }

    /**
     * 格式化日期时闿
     * <p>
     * 日期时间格式yyyy-MM-dd HH:mm:ss
     *
     * @return
     */
    public static Date formatDatetime(String regex) {
        Date time = getDateTime(new Date(), regex);
        return time;
    }


    /**
     * 获得当前日期时间
     * <p>
     * 日期格式yyyyMMdd HHmmss
     */
    public static String currentDatetimeNoSep() {
        return getDateTimeStr(new Date(), "yyyyMMdd HHmmss");
    }

    /**
     * 格式化日朿
     * <p>
     * 日期格式yyyy-MM-dd
     *
     * @return
     */
    public static String formatDate(Date date) {
        return getDateTimeStr(new Date(), Y_M_D);
    }

    /**
     * 获得当前时间
     * <p>
     * 时间格式HH:mm:ss
     *
     * @return
     */
    public static String currentTime() {
        return getDateTimeStr(new Date(), HMS);
    }

    /**
     * 格式化时闿
     * <p>
     * 时间格式HH:mm:ss
     *
     * @return
     */
    public static String formatTime(Date date) {
        return getDateTimeStr(date, HMS);
    }

    /**
     * 获得当前时间皿code>java.util.Date</code>对象
     *
     * @return
     */
    public static Date now() {
        return new Date();
    }

    public static Calendar calendar() {
        Calendar cal = GregorianCalendar.getInstance(Locale.CHINESE);
        cal.setFirstDayOfWeek(Calendar.MONDAY);
        return cal;
    }

    /**
     * 获得当前时间的毫秒数
     * <p>
     * 详覺{@link System#currentTimeMillis()}
     *
     * @return
     */
    public static long millis() {
        return System.currentTimeMillis();
    }

    /**
     * 获得当前Chinese年份
     *
     * @return
     */
    public static int year() {
        return calendar().get(Calendar.YEAR);
    }

    /**
     * 获得当前Chinese月份
     *
     * @return
     */
    public static int month() {
        return calendar().get(Calendar.MONTH) + 1;
    }

    /**
     * 获得月份中的第几夿
     *
     * @return
     */
    public static int dayOfMonth() {
        return calendar().get(Calendar.DAY_OF_MONTH);
    }

    /**
     * 今天是星期的第几夿
     *
     * @return
     */
    public static int dayOfWeek() {
        return calendar().get(Calendar.DAY_OF_WEEK);
    }

    /**
     * 今天是年中的第几夿
     *
     * @return
     */
    public static int dayOfYear() {
        return calendar().get(Calendar.DAY_OF_YEAR);
    }

    /**
     * 判断原日期是否在目标日期之前
     *
     * @param src
     * @param dst
     * @return
     */
    public static boolean isBefore(Date src, Date dst) {
        return src.before(dst);
    }

    /**
     * 判断原日期是否在目标日期之后
     *
     * @param src
     * @param dst
     * @return
     */
    public static boolean isAfter(Date src, Date dst) {
        return src.after(dst);
    }

    /**
     * 判断两日期是否相吿
     *
     * @param date1
     * @param date2
     * @return
     */
    public static boolean isEqual(Date date1, Date date2) {
        return date1.compareTo(date2) == 0;
    }

    /**
     * 判断某个日期是否在某个日期范囿
     *
     * @param beginDate 日期范围弿ƾ
     * @param endDate   日期范围结束
     * @param src       霿Ơ判断的日朿
     * @return
     */
    public static boolean between(Date beginDate, Date endDate, Date src) {
        return beginDate.before(src) && endDate.after(src);
    }

    /**
     * 获得当前月的最后日期
     * <p>
     * HH:mm:ss丿，毫秒为999
     *
     * @return
     */
    public static Date lastDayOfMonth() {
        Calendar cal = calendar();
        cal.set(Calendar.DAY_OF_MONTH, 0); // M月置雿
        cal.set(Calendar.HOUR_OF_DAY, 0);// H置零
        cal.set(Calendar.MINUTE, 0);// m置零
        cal.set(Calendar.SECOND, 0);// s置零
        cal.set(Calendar.MILLISECOND, 0);// S置零
        cal.set(Calendar.MONTH, cal.get(Calendar.MONTH) + 1);// 月份+1
        cal.set(Calendar.MILLISECOND, -1);// 毫秝-1
        return cal.getTime();
    }

    /**
     * 获得当前月的第一天日期
     * <p>
     * HH:mm:ss SS为零
     *
     * @return
     */
    public static Date firstDayOfMonth() {
        Calendar cal = calendar();
        cal.set(Calendar.DAY_OF_MONTH, 1); // M月置1
        cal.set(Calendar.HOUR_OF_DAY, 0);// H置零
        cal.set(Calendar.MINUTE, 0);// m置零
        cal.set(Calendar.SECOND, 0);// s置零
        cal.set(Calendar.MILLISECOND, 0);// S置零
        return cal.getTime();
    }


    /**
     * 获取当前时间的前几个小时
     *
     * @参数： day int 加减小时数
     */
    public static String getDateTimeBeforOrAlterHour(int hour) {
        // 此时打印它获取的是系统当前时间
        Calendar calendar = Calendar.getInstance();
        // 得到前、后几个小时
        calendar.add(Calendar.HOUR, hour);
        return getDateTimeStr(calendar.getTime(), YMDHMS);
    }

    /**
     * 获取当前时间的前几分钟
     *
     * @参数： day int 加减分钟数
     */
    public static String getDateTimeBeforOrAlterMin(int min) {
        Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时间
        // 得到前、后几分钟时间
        calendar.add(Calendar.MINUTE, min);
        return getDateTimeStr(calendar.getTime(), YMDHMS);
    }


    private static Date weekDay(int week) {
        Calendar cal = calendar();
        cal.set(Calendar.DAY_OF_WEEK, week);
        return cal.getTime();
    }

    /**
     * 获得周五日期
     * <p>
     * 注：日历工厂方法{@link #calendar()}设置类每个星期的第一天为Monday，US等每星期第一天为sunday
     *
     * @return
     */
    public static Date friday() {
        return weekDay(Calendar.FRIDAY);
    }

    /**
     * 获得周六日期
     * <p>
     * 注：日历工厂方法{@link #calendar()}设置类每个星期的第一天为Monday，US等每星期第一天为sunday
     *
     * @return
     */
    public static Date saturday() {
        return weekDay(Calendar.SATURDAY);
    }

    /**
     * 获得周日日期
     * <p>
     * 注：日历工厂方法{@link #calendar()}设置类每个星期的第一天为Monday，US等每星期第一天为sunday
     *
     * @return
     */
    public static Date sunday() {
        return weekDay(Calendar.SUNDAY);
    }

    /**
     * 获取星期中的第一天
     *
     * @return
     */
    public static String getFirstWorkDate() {
        return getDateTimeStr(weekDay(Calendar.MONDAY), Y_M_D);
    }

    /**
     * 获取星期中的最后一天
     *
     * @return
     */
    public static String getLastWorkDate() {
        return getDateTimeStr(weekDay(Calendar.FRIDAY), Y_M_D);
    }

    /**
     * 将字符串日期时间转换成java.util.Date类型
     * <p>
     * 日期时间格式yyyy-MM-dd HH:mm:ss
     *
     * @param datetime
     * @return
     */
    public static Date parseDatetime(String datetime) {
        return getDateTime(datetime, YMDHMS);
    }

    /**
     * 将字符串日期转换成java.util.Date类型
     * <p>
     * 日期时间格式yyyy-MM-dd
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public static Date parseDate(String date) throws ParseException {
        return getDateTime(date, Y_M_D);
    }

    /**
     * 将字符串日期转换成java.util.Date类型
     * <p>
     * 时间格式 HH:mm:ss
     *
     * @param time
     * @return
     * @throws ParseException
     */
    public static Date parseTime(String time) throws ParseException {
        return getDateTime(time, HMS);
    }

    /**
     * 根据自定义pattern将字符串日期转换成java.util.Date类型
     *
     * @param time
     * @param pattern
     * @return
     * @throws ParseException
     */
    public static Date parseDatetime(String time, String pattern) {
        return getDateTime(time, pattern);
    }

    /**
     * 方法名：getCurrentDateAlter 描述：获取当前日期的前几天䀥Ў几夿
     *
     * @参数＿ day int 加减天数
     */
    public static String getCurrentDateAlter(int day) {
        Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时闿
        calendar.add(Calendar.DATE, day); // 得到前一夿
        return getDateTimeStr(calendar.getTime(), Y_M_D);
    }

    /**
     * 方法名：getBeforMonthDateStr 描述：获取上个月时间
     *
     * @参数＿ day int 加减天数
     * @返回值类型： String
     * @创建时间＿ 2014-7-23
     * @创建者：陈威桿
     * @变更记录＿014-7-23上午11:02:15 by
     */
    public static String getBeforMonthDateStr(int day, String regex) {
        Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时闿
        calendar.add(Calendar.MONTH, day); // 得到前一夿
        if (StringUtils.isEmpty(regex)) {
            regex = Y_M_D;
        }
        return getDateTimeStr(calendar.getTime(), regex);
    }

    /**
     * TODO 获取当前日期的前几天后几天
     *
     * @param day 加减天数
     * @return 日期时间格式yyyy-MM-dd HH:mm:ss
     * @author zhanghan
     * @date 2016-10-12
     */
    public static String getCurrentDateTimeAlter(int day) {
        Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时闿
        calendar.add(Calendar.DATE, day); // 得到前一夿
        return getDateTimeStr(calendar.getTime(), YMDHMS);
    }

    /**
     * 获取当前日期的前几天、后几天
     *
     * @param day 加减天数
     * @return
     * @author zhanghan
     * @date 2016-8-10
     */
    public static String getCurrentDateAlterNoSep(int day) {
        Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时闿
        calendar.add(Calendar.DATE, day); // 得到前一夿
        return getDateTimeStr(calendar.getTime(), "yyyyMMdd");
    }

    public static Date getCurrentDateBefore(int day) {
        Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时闿
        calendar.add(Calendar.DATE, day); // 得到前一夿
        return calendar.getTime();
    }

    public static String getCurrentDateAlter(String date, int day) throws ParseException {
        Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时闿
        calendar.setTime(getDateTime(date, Y_M_D));
        calendar.add(Calendar.DATE, day); // 得到前一夿
        return getDateTimeStr(calendar.getTime(), Y_M_D);
    }

    public static String getIncomeCurrentDateAlter(String date, int day) throws ParseException {
        Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时闿
        calendar.setTime(getDateTime(date, YMDHMS));
        calendar.add(Calendar.DATE, day); // 得到前一夿
        return getDateTimeStr(calendar.getTime(), YMDHMS);
    }


    /**
     * 获取日期是星期几
     *
     * @return
     */
    public static String dayOfWeekInChines() {
        int dayOfWeek = DateUtils.dayOfWeek();
        return DateUtils.dayOfWeek[dayOfWeek - 1];
    }


    /**
     * 获取日期是第几周
     *
     * @param date
     * @return
     */
    public static String getWeek(String date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getDateTime(date, Y_M_D));
        int week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (week_index < 0) {
            week_index = 0;
        }
        String rst = dayOfWeek[week_index];
        return rst;
    }

    public static List<String> getFiveWorkDayFromTody(String date1, String date2) throws ParseException {
        List<String> resList = new ArrayList<String>();
        if (date1 == null) {
            date1 = DateUtils.getCurrentDateAlter(-7);
        }
        Date startDate = getDateTime(date1, Y_M_D);
        if (date2 == null) {
            date2 = DateUtils.currentDatetimeStr();
        }
        Date today = getDateTime(date2, Y_M_D);
        while (!startDate.after(today)) {
            String week = getWeek(getDateTimeStr(startDate, Y_M_D));
            if (!(dayOfWeek[0].equals(week) || dayOfWeek[6].equals(week))) {
                resList.add(week);
            }
            Calendar cal = Calendar.getInstance();
            cal.setTime(startDate);
            cal.add(Calendar.DAY_OF_MONTH, 1);
            startDate = cal.getTime();
        }
        return resList;
    }


    /**
     * 计算两个日期之间相差的天敿
     *
     * @param startDateStr 较小的时闿
     * @param endDateStr   较大的时闿
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(String startDateStr, String endDateStr) {
        Date startDate = getDateTime(startDateStr, Y_M_D);
        Date endDate = getDateTime(endDateStr, Y_M_D);
        int rst = daysBetween(startDate, endDate);
        return rst;
    }

    /**
     * 计算两个日期之间相差的天敿
     *
     * @param startDate 较小的时闿
     * @param endDate   较大的时闿
     * @return 相差天数
     * @throws ParseException
     */
    public static int daysBetween(Date startDate, Date endDate) {

        SimpleDateFormat sdf = new SimpleDateFormat(Y_M_D);
        startDate = getDateTime(startDate, Y_M_D);
        endDate = getDateTime(endDate, Y_M_D);

        Calendar cal = Calendar.getInstance();
        cal.setTime(startDate);
        long time1 = cal.getTimeInMillis();
        cal.setTime(endDate);
        long time2 = cal.getTimeInMillis();

        long between_days = (time2 - time1) / (1000 * 3600 * 24);
        int rst = Integer.parseInt(String.valueOf(between_days));
        return rst;
    }


    /**
     * 获取星期中的某一天
     *
     * @param date
     * @return
     * @throws ParseException
     */
    public static String getWeekOfNum(String date) throws ParseException {
        Calendar cal = Calendar.getInstance();
        cal.setTime(getDateTime(date, Y_M_D));
        int week_index = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (week_index < 0) {
            week_index = 0;
        }
        return "" + week_index;
    }


    /**
     * TODO 老外习惯,获取上几周第一天(周日)
     *
     * @param date
     * @param day  上几周
     * @return 返回类型yyyy-MM-dd
     * @throws ParseException
     * @author zhanghan
     * @date 2016-9-9
     */
    public static String getLastDay(String date, int day, int dayOfWeek) throws ParseException {
        Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时闿
        calendar.setTime(getDateTime(date, Y_M_D));
        calendar.add(Calendar.DAY_OF_WEEK_IN_MONTH, day);
        calendar.set(Calendar.DAY_OF_WEEK, dayOfWeek);
        return getDateTimeStr(calendar.getTime(), Y_M_D);
    }

    /**
     * 老外习惯,获取上周第一天(周日)
     *
     * @param date 传入当前日期
     * @return 返回类型yyyy-MM-dd
     */
    public static String getLastSunDay(String date) throws ParseException {
        return getLastSunDay(date, -1);
    }


    /**
     * TODO 老外习惯,获取上几周第一天(周日)
     *
     * @param date
     * @param day  上几周
     * @return 返回类型yyyy-MM-dd
     */
    public static String getLastSunDay(String date, int day) throws ParseException {
        String lastDay = getLastDay(date, day, Calendar.SUNDAY);
        return lastDay;
    }

    /**
     * TODO 老外习惯,获取上周最后一天(周六)
     *
     * @param date
     * @return 返回类型yyyy-MM-dd
     */
    public static String getLastSaturday(String date) throws ParseException {
        String lastDay = getLastDay(date, -1, Calendar.SATURDAY);
        return lastDay;
    }

    /**
     * TODO 老外习惯,获取上几周最后一天(周六)
     *
     * @param date
     * @param day  上几周
     * @return 返回类型yyyy-MM-dd
     */
    public static String getLastSaturday(String date, int day) throws ParseException {
        String lastDay = getLastDay(date, day, Calendar.SATURDAY);
        return lastDay;
    }


    /**
     * 获取前后day月最后一天 正数为未来{ay朿负数为过去day朿
     *
     * @param date  传入当前日期
     * @param regex 返回日期格式类型
     */

    public static String getDayOfMonth(String date, int day, int dayOfMonth, String regex) throws ParseException {

        if (StringUtils.isEmpty(regex)) {
            regex = Y_M_D;
        }

        Calendar cal = calendar();
        cal.setTime(dateFormat_ymd.parse(date));
        cal.add(Calendar.MONTH, day);
        cal.set(Calendar.DAY_OF_MONTH, dayOfMonth); // M月置1

        SimpleDateFormat dateFormat = new SimpleDateFormat(regex);
        String format = dateFormat.format(cal.getTime());
        return format;
    }


    /**
     * 获取前后day月最后一天， 正数为未来day,负数为过去day
     *
     * @param date 传入当前日期
     * @return 返回类型yyyy-MM-dd
     */
    public static String getMonthDay(String date, int day) throws ParseException {
        String dayOfMonth = getDayOfMonth(date, day + 1, 0, Y_M_D);
        return dayOfMonth;
    }


    /**
     * 获取前后day月第几天数， 正数为未来day,负数为过去day
     *
     * @param date
     * @return 返回类型yyyy-MM-dd
     */
    public static String getMonthFirstDay(String date, int day) throws ParseException {
//        Calendar cal = calendar();
//        SimpleDateFormat dateFormat = new SimpleDateFormat(Y_M_D);
//        cal.setTime(dateFormat.parse(date));
//        cal.add(Calendar.MONTH, day);
//        cal.set(Calendar.DAY_OF_MONTH, 1); // M月置1
//        return formatDate(cal.getTime());
        String dayOfMonth = getDayOfMonth(date, day, 1, Y_M_D);
        return dayOfMonth;
    }


    /**
     * 获取传入时间的当月第一天
     *
     * @param @param  date
     * @param @param  day
     * @param @return
     * @return String yyyy-MM-dd
     */
    public static String getMonthFirstDayStr(String date, int day) throws ParseException {
        String dayOfMonth = getDayOfMonth(date, day, 1, YMDHMS);
        return dayOfMonth;
    }

    /**
     * 获取传入时间的月份最后一天一天
     *
     * @param @param  date
     * @param @param  day
     * @param @return
     * @return String yyyy-MM-dd
     */
    public static String getMonthLastDay(String date, int day) throws ParseException {
        Calendar cal = calendar();
        String dayOfMonth = getDayOfMonth(date, day, cal.getActualMaximum(Calendar.DAY_OF_MONTH), YMDHMS);
        return dayOfMonth;
    }


    /**
     * TODO 获取某时间的前后几小时 返回类型 yyyy-MM-dd HH:mm:ss
     *
     * @param hour
     * @param date 正数后几天,负数前几天
     */
    public static String getDateTimeAlterHour(Date date, int hour) {
        // 得到前一个小时
        Date time = getDateTimeForField(date, Calendar.HOUR, hour);
        String yestedayDate = datetimeFormat_ymdhms.format(time);
        return yestedayDate;
    }

    /**
     * TODO 获取某时间的前后几天 返回类型 yyyy-MM-dd HH:mm:ss
     *
     * @param date
     * @param day  正数后几天,负数前几天
     */
    public static String getDateTimeBeforOrAlterDay(Date date, int day, String regex) {

        if (StringUtils.isEmpty(regex)) {
            regex = YMDHMS;
        }

        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.DATE, day);
        return getDateTimeStr(calendar.getTime(), regex);
    }

    /**
     * TODO 中国习惯上一周第一天(上周一)
     *
     * @param date
     * @param day
     * @return
     * @throws ParseException
     */
    public static String getMonday(String date, int day) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(parseDate(date));
        System.out.println(calendar.get(Calendar.DAY_OF_WEEK));
        if (calendar.get(Calendar.DAY_OF_WEEK) == 1) {
            --day;
        }
        calendar.add(Calendar.DAY_OF_WEEK_IN_MONTH, day);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return formatDate(calendar.getTime());
    }

    /**
     * TODO 中国习惯上一周第一天(周一)
     *
     * @return
     * @throws ParseException
     */
    public static String getMonday(int day) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        System.out.println(calendar.get(Calendar.DAY_OF_WEEK));
        if (calendar.get(Calendar.DAY_OF_WEEK) == 1) {
            --day;
        }
        calendar.add(Calendar.DAY_OF_WEEK_IN_MONTH, day);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY);
        return formatDate(calendar.getTime());
    }

    /**
     * TODO 中国习惯上一周最后一天(上周日)
     *
     * @param date
     * @param day
     * @return
     * @throws ParseException
     */
    public static String getSun(String date, int day) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(parseDate(date));
        System.out.println(calendar.get(Calendar.DAY_OF_WEEK));
        if (calendar.get(Calendar.DAY_OF_WEEK) != 1) {
            ++day;
        }
        calendar.add(Calendar.DAY_OF_WEEK_IN_MONTH, day);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        return formatDate(calendar.getTime());
    }

    /**
     * TODO 中国习惯上一周最后一天(周日)
     *
     * @param day
     * @return
     * @throws ParseException
     */
    public static String getSun(int day) throws ParseException {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        System.out.println(calendar.get(Calendar.DAY_OF_WEEK));
        if (calendar.get(Calendar.DAY_OF_WEEK) != 1) {
            ++day;
        }
        calendar.add(Calendar.DAY_OF_WEEK_IN_MONTH, day);
        calendar.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
        return formatDate(calendar.getTime());
    }


    /**
     * TODO 获取某个时间多少时间后的时间
     *
     * @param date
     * @param field 类型,Calendar里包含的几个类型
     * @param num:  数字
     * @return
     */
    public static Date getDateTimeForField(Date date, int field, int num) {
        Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时闿
        calendar.setTime(date);
        calendar.add(field, num); // 得到前几/分钟/毫秒
        return calendar.getTime();
    }


    /**
     * TODO 获取某时间的前后几分钟 返回类型 yyyy-MM-dd HH:mm:ss
     *
     * @param date
     * @param minute 正数后分钟,负数前分钟
     */
    public static String getDateTimeBeforOrAlterMinStr(Date date, int minute, String regex) {
        if (StringUtils.isEmpty(regex)) {
            regex = YMDHMS;
        }
        Date date1 = getDateTimeForField(date, Calendar.MINUTE, minute);
        return getDateTimeStr(date1, regex);
    }

    /**
     * TODO 获取某时间的前后几分钟 返回类型 yyyy-MM-dd HH:mm:ss
     *
     * @param date
     * @param minute 正数后分钟,负数前分钟
     */
    public static Date getDateTimeBeforOrAlterMin(Date date, int minute) {
        Date date1 = getDateTimeForField(date, Calendar.MINUTE, minute);
        return date1;
    }

    /**
     * TODO 获取某个时间多少时间后的时间
     *
     * @param date
     * @param milliSecond
     * @return
     */
    public static Date getDateAlterForMillSecond(Date date, int milliSecond) {
        Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时闿
        calendar.setTime(date);
        calendar.add(Calendar.MILLISECOND, milliSecond); // 得到前几毫秒
        return calendar.getTime();
    }


    /**
     * 获取当前月的最后一天
     *
     * @param @param  date
     * @param @return
     * @param @throws ParseException
     * @return String
     */
    public static String getMonthLastDayStr(String date) throws ParseException {
        Calendar c = Calendar.getInstance();
        c.setTime(getDateTime(date, YMDHMS));
        c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH));
        return getDateTimeStr(c.getTime(), YMDHMS);
    }

    /**
     * 将utc 时间转为本地时间
     *
     * @param time
     * @param partten
     * @return
     * @throws ParseException
     */
    public static String utc2Local(String time, String partten) throws ParseException {

        if (StringUtils.isEmpty(partten)) {
            partten = YMDHMS;
        }
        String pattern = time.contains(".") ? "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" : "yyyy-MM-dd'T'HH:mm:ss'Z'";
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
        return getDateTimeStr(sdf.parse(time), partten);
    }

}
